package com.cherry.androidviewdemo.widget

import android.content.Context
import android.util.AttributeSet
import android.view.ViewGroup
import java.lang.Math.max

/**
 * 简单的流式布局
 * @author DongMS
 * @since 2020/5/20
 */
class FlowLayout : ViewGroup {

    constructor (context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        var height = 0 //整个布局的高度
        var width = 0 //整个布局的宽度
        var lineWidth = 0 //一行的宽度
        var lineHeight = 0 //一行的高度

        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val widthSize = MeasureSpec.getSize(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)
        val heightSize = MeasureSpec.getSize(heightMeasureSpec)

        val childCount = childCount
        for (i in 0 until childCount) {
            val childView = getChildAt(i)
            //为指定的子视图进行measure操作
            measureChild(childView, widthMeasureSpec, heightMeasureSpec)
            val lp = childView.layoutParams as MarginLayoutParams
            val childWidth = childView.measuredWidth + lp.leftMargin + lp.rightMargin
            val childHeight = childView.measuredHeight + lp.topMargin + lp.bottomMargin
            //lineWidth已经存在的宽度,childWidth将要添加的宽度
            if (lineWidth + childWidth > widthSize) {
                //换行
                width = max(lineWidth, childWidth)
                height += lineHeight

                lineWidth = childWidth
                lineHeight = childHeight

            } else {
                lineWidth += childWidth
                lineHeight = max(lineHeight, childHeight)
            }

            //最后一行单独处理
            if (i == childCount - 1) {
                width = max(width, lineWidth)
                height += lineHeight
            }
        }

        setMeasuredDimension(if (widthMode == MeasureSpec.EXACTLY) widthSize else width, if (heightMode == MeasureSpec.EXACTLY) heightSize else height)

    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {

        var left = 0
        var top = 0
        var lineWidth = 0 //一行的宽度
        var lineHeight = 0 //一行的高度

        val childCount = childCount
        val parentWidth = measuredWidth
        for (i in 0 until childCount) {
            val childView = getChildAt(i)
            val lp = childView.layoutParams as MarginLayoutParams
            val childWidth = childView.measuredWidth + lp.leftMargin + lp.rightMargin
            val childHeight = childView.measuredHeight + lp.topMargin + lp.bottomMargin

            if (childWidth + lineWidth > parentWidth) {
                //换行
                top += lineHeight
                left = 0
                lineWidth = childWidth
                lineHeight = childHeight
            } else {
                lineWidth += childWidth
                lineHeight = max(lineHeight, childHeight)
            }

            val rl = left + lp.leftMargin
            var rr = rl + childView.measuredWidth
            if (rr > parentWidth - lp.rightMargin) {
                rr = parentWidth - lp.rightMargin
            }
            val rt = top + lp.topMargin
            val rb = rt + childView.measuredHeight

            childView.layout(rl, rt, rr, rb)
            left += childWidth
        }

    }

    //margin

    override fun generateDefaultLayoutParams(): LayoutParams {
        return MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
    }

    override fun generateLayoutParams(p: LayoutParams?): LayoutParams {
        return MarginLayoutParams(p)
    }

    override fun generateLayoutParams(attrs: AttributeSet?): LayoutParams {
        return MarginLayoutParams(context, attrs)
    }
}